package com.gang.mars.aop.test;

import com.gang.mars.aop.proxy.cglib.filter.GangDefaultCallbacFilter;
import com.gang.mars.aop.proxy.cglib.methodinterceptor.GangDefaultMethodInterceptor;
import com.gang.mars.aop.proxy.cglib.methodinterceptor.GangSmartMethodInterceptor;
import com.gang.mars.aop.proxy.jdk.GangDefaultInvocationHandlerImpl;
import com.gang.mars.aop.proxy.springproxy.intercptor.GangMethodInterceptorImpl;
import com.gang.mars.aop.proxy.springproxy.methodadvice.GangAfterReturningAdviceImpl;
import com.gang.mars.aop.proxy.springproxy.methodadvice.GangMethodBeforeAdviceImpl;
import com.gang.mars.aop.proxy.springproxy.methodadvice.GangPointcutAdvisorIml;
import com.gang.mars.aop.proxy.springproxy.methodadvice.GangThrowAdviceImpl;
import com.gang.mars.aop.service.HelloWorldService;
import com.gang.mars.aop.service.impl.HelloWorldServiceImpl;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 类说明：gang.chen springboot深度实践
 *
 * @author gang.chen
 * @since 2022/5/14
 */
public class AopTestCase {


    public static void main(String[] args) {
        //CglibTest1();
        //CglibTest2();
        //jdkTest3();
        //proxyFactoryTest1();
        //proxyFactoryTest2();
        //proxyFactoryTest3();
        //proxyFactoryTest4();
        proxyFactoryTest5();
    }

    public static void proxyFactoryTest5(){
        HelloWorldServiceImpl originalService = new HelloWorldServiceImpl();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(originalService);
        proxyFactory.addAdvisor(new GangPointcutAdvisorIml());
        HelloWorldServiceImpl proxyService = (HelloWorldServiceImpl) proxyFactory.getProxy();
        proxyService.test1();
    }

    public static void proxyFactoryTest4(){
        HelloWorldServiceImpl originalService = new HelloWorldServiceImpl();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(originalService);
        proxyFactory.addAdvice(new GangMethodInterceptorImpl());
        proxyFactory.addAdvice(new GangMethodBeforeAdviceImpl());
        HelloWorldServiceImpl serviceProxy = (HelloWorldServiceImpl) proxyFactory.getProxy();
        serviceProxy.test1();
    }

    public static void proxyFactoryTest3(){
        HelloWorldServiceImpl originalService = new HelloWorldServiceImpl();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(originalService);
        proxyFactory.addAdvice(new GangThrowAdviceImpl());
        HelloWorldServiceImpl proxyService = (HelloWorldServiceImpl) proxyFactory.getProxy();
        proxyService.test4();
    }

    public static void proxyFactoryTest2(){
        HelloWorldServiceImpl originalService = new HelloWorldServiceImpl();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(originalService);
        proxyFactory.addAdvice(new GangAfterReturningAdviceImpl());
        HelloWorldServiceImpl proxyService = (HelloWorldServiceImpl) proxyFactory.getProxy();
        proxyService.test1();
    }

    public static void proxyFactoryTest1(){
        HelloWorldServiceImpl originalService = new HelloWorldServiceImpl();
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(originalService);
        proxyFactory.addAdvice(new GangMethodBeforeAdviceImpl());
        HelloWorldServiceImpl proxyService = (HelloWorldServiceImpl) proxyFactory.getProxy();
        proxyService.test1();
    }

    /**
     * JKD 代理要提供接口类
     * */
    public static void jdkTest3(){
        HelloWorldService originalService = new HelloWorldServiceImpl();
        HelloWorldService proxyService = (HelloWorldService) Proxy.newProxyInstance(AopTestCase.class.getClassLoader(), new Class[]{HelloWorldService.class}, new GangDefaultInvocationHandlerImpl());
        proxyService.test1();
        originalService.test1();
    }

    /**
     *
     * */
    public static void CglibTest2(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloWorldServiceImpl.class);
        enhancer.setCallbacks(new Callback[]{new GangDefaultMethodInterceptor(),new GangSmartMethodInterceptor()});
        enhancer.setCallbackFilter(new GangDefaultCallbacFilter());
        HelloWorldServiceImpl proxyService  = (HelloWorldServiceImpl) enhancer.create();
        proxyService.test2();
    }

    public static void  CglibTest1(){
        HelloWorldServiceImpl orignalService = new HelloWorldServiceImpl();

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(HelloWorldServiceImpl.class);

        enhancer.setCallbacks(new Callback[]{ new MethodInterceptor() {

            /**
             * @param  o 代理对象，继承于源生对象子对象
             * @param method 源生对象方法
             * @param objects 源生对象方法参数
             * @param methodProxy 代理方法
             * */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                Object result = methodProxy.invoke(orignalService, objects);

                Object resutl2 = method.invoke(orignalService, objects);

                Object resutl3 = methodProxy.invokeSuper(o, objects);

                System.out.println("after test method plus +++");
                return result;
            }
        }});

        HelloWorldServiceImpl proxyService = (HelloWorldServiceImpl) enhancer.create();
        proxyService.test1();
    }
}
